#!/usr/bin/env python3

import sys
import os
import shutil
import tomllib

def flatten_dict(nested_dict, parent_key=''):
    items = {}
    for key, value in nested_dict.items():
        new_key = f"{parent_key}.{key}" if parent_key else key
        if isinstance(value, dict):
            items.update(flatten_dict(value, new_key))
        else:
            items[new_key] = value
    return items

print(f"Begin!")

release_build = True if len(sys.argv) > 1 and sys.argv[1] == "release" else False
build_name = "release" if release_build else "debug"

if not os.path.exists("DeployConfig.toml"):
	exit(1)


with open("DeployConfig.toml", "rb") as f:
	config = tomllib.load(f)


target_project_path = "godot"
if "project" not in config:
	config["project"] = {}

if "target" not in config["project"]:
	print("No target specified, output to current folder")
	if not os.path.exists("godot"):
		os.mkdir("godot")
else:
	target_project_path = config["project"]["target"] 

if "name" in config["project"]:
	project_name = config["project"]["name"]
elif os.path.exists("Cargo.toml"):
	with open("Cargo.toml", "rb") as f:
		cargo = tomllib.load(f)

	if "workspace" in cargo:
		with open(cargo["workspace"]["members"][0] + "/Cargo.toml", "rb") as f:
			cargo = tomllib.load(f)

	project_name = cargo["package"]["name"]


print("Project:\n\t{}\nTarget:\n\t{}".format(project_name, target_project_path))

extension_path = f"{target_project_path}/libs"
target_manifest_path = f"{extension_path}/{project_name}.gdextension"

print("Extension:\n\t{}\n\t{}".format(extension_path, target_manifest_path))

targets = config["target"]

print("Compiling...")

installed_targets = os.popen("rustup target list").read()
for plat, arches in targets.items():
	for arch, data in arches.items():
		toolchain = next(toolchain for toolchain in data["toolchains"] if f"{toolchain} (installed)" in installed_targets)

		print(f"Building {plat}.{build_name}.{arch} with {toolchain}")
		build_cmd = f"cargo build {"--release" if release_build else ""} --target={toolchain}"
		if os.system(build_cmd) != 0:
			print("Build failed.")
			exit(1)
		
		data["toolchain"] = toolchain


print("Copying...")


ext_config = {
	"entry_symbol": f"\"{project_name}_init\"",
	"compatibility_minimum": 4.4,
	"reloadable": "false",
}
ext_libs = {}

if os.path.exists(target_manifest_path):
	with open(target_manifest_path, "rb") as f:
		exist_ext = tomllib.load(f)
	
	for arch, path in flatten_dict(exist_ext["libraries"]).items():
		ext_libs[arch] = f'"{path}"'

bin_path = f"{extension_path}/bin/{build_name}"

for plat, arches in targets.items():
	for arch, data in arches.items():
		binary = data["binary_format"].format(project_name)
		lib_path = f"{bin_path}/{plat}/{arch}"
		os.makedirs(lib_path, exist_ok=True)
		shutil.copy(f"target/{data["toolchain"]}/{build_name}/{binary}", lib_path)
		ext_libs[f"{plat}.{build_name}.{arch}"] = f'"bin/{build_name}/{plat}/{arch}/{binary}"'

with open(f"{extension_path}/bin/.gdignore", "w+") as f:
	pass

with open(target_manifest_path, "w") as f:
	f.write("[configuration]\n")
	for name, prop in ext_config.items():
		f.write(f"{name} = {prop}\n")
	
	f.write("\n[libraries]\n")
	for name, prop in ext_libs.items():
		f.write(f"{name} = {prop}\n")

print("Done!")